﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ResourceEnumerator.Inrastructure
{
    [Export(typeof(IEnumerationService))]
    public class EnumerationService : IEnumerationService
    {
        private const string ResourceDictionaryKey = "ResourceDictionary";
        private const string KeyKey = "Key";

        public bool IsValid(string documentText)
        {
            try
            {
                var document = XDocument.Parse(documentText);
                return document.Elements().FirstOrDefault(x => x.Name.LocalName == ResourceDictionaryKey) != null;
            }
            catch (Exception ex)
            {
                DebugLogger.LogMessage("An exception occurred while validating");
                DebugLogger.LogMessage(ex.Message);
                DebugLogger.LogMessage(ex.StackTrace);

                return false;
            }
        }

        public Task<IEnumerable<ResourceItem>> EnumerateAsync(string documentText)
        {
            return Task.Run(() =>
            {
                if (!IsValid(documentText)) return Task.FromResult(Enumerable.Empty<ResourceItem>());

                var document = GetParsedDocument(documentText);
                if (document == null) return Task.FromResult(Enumerable.Empty<ResourceItem>());

                var resourceDictionaryElement =
                    document.Elements().First(x => x.Name.LocalName == "ResourceDictionary");
                var elementList = resourceDictionaryElement.Elements().ToList();
                var list = new List<ResourceItem>();
                elementList.ForEach(element =>
                {
                    var keyAttribute = element.Attributes().FirstOrDefault(x => x.Name.LocalName == KeyKey);
                    if (string.IsNullOrEmpty(keyAttribute?.Value))
                    {
                        DebugLogger.LogMessage($"Couldn't find x:Key attribute on {element.Name.LocalName}");
                        return;
                    }
                    DebugLogger.LogMessage($"Adding resource with Key {keyAttribute.Value}");
                    list.Add(new ResourceItem(keyAttribute.Value, element.Name.LocalName));
                });
                return Task.FromResult((IEnumerable<ResourceItem>) list);
            });
        }

        XDocument GetParsedDocument(string documentText)
        {
            try
            {
                return XDocument.Parse(documentText);
            }
            catch (Exception ex)
            {
                DebugLogger.LogMessage("Document Text parse failed.");
                DebugLogger.LogMessage(ex.Message);
                DebugLogger.LogMessage(ex.StackTrace);
                return null;
            }
        }
    }
}
